package com.thinkSoft.Location.Services;
import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.thinkSoft.Location.R;
import com.thinkSoft.Location.Activities.UIDashboard;
import com.thinkSoft.Location.Helpers.Debugger;
import com.thinkSoft.Location.Lib.DataFunc;
import com.thinkSoft.Location.Lib.WebData;

public class Background extends Service implements LocationListener {
	private MyReceiver myReceiver;
	public Boolean tracking = false;
	private Long lastDataSend = 0L;
	private LocationManager lm;
	private Debugger debug = new Debugger();
	private static String KEY_SUCCESS = "success";
	private static String KEY_ERROR_MSG = "error_msg";
	public final static String TrackAction = "com.thinkSoft.Location.track";
	private Notification notification;
	private NotificationManager notificationManager;
	private WakeLock wakeLock;

	@Override
	public void onCreate() {
		super.onCreate();
		debug.postLog(Log.INFO, "Service", "onCreate()");
		myReceiver = new MyReceiver(this);
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(Background.TrackAction);
		registerReceiver(myReceiver, intentFilter);
		postNotification("Voo","Service running.","Voo - Service Running", UIDashboard.class);
	}

	private void postNotification(String title, String text, String ticker, Class<?> Cls){

		if (notificationManager == null){
			notificationManager 
			= (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
		}
		notificationManager.cancelAll();
		Intent intent = new Intent(this, Cls);
		PendingIntent pendingIntent 
		= PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_CLEAR_TASK);
		NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
		builder
		.setSmallIcon(R.drawable.ic_stat_example)
		.setContentTitle(title)
		.setContentText(text)
		.setTicker(ticker)
		.setOngoing(true)
		.setLights(0xFFFF0000, 500, 500)
		.setContentIntent(pendingIntent)
		.setAutoCancel(false);

		notification = builder.build();
		notificationManager.notify(R.drawable.ic_stat_example, notification);
	}


	@Override
	public void onStart(Intent intent, int startId) {
		debug.postLog(Log.INFO, "Service", "onStart()");
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		releaseWakeLock();
		if (lm != null)
			lm.removeUpdates(this);
		notificationManager.cancelAll();
		unregisterReceiver(myReceiver);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	public void toggleTracking(){
		Log.e("","TOGGLING GPS");
		if (!tracking){
			aquireWakeLock();
			tracking = true;
			lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
			Criteria criteria = new Criteria();
			criteria.setAccuracy(Criteria.ACCURACY_FINE);
			String provider = lm.getBestProvider(criteria, true);
			lm.requestLocationUpdates(provider, 0, 0, this);
			lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
			postNotification("Voo","Tracking location.","Started Tracking", UIDashboard.class);
		} else{
			releaseWakeLock();
			lm.removeUpdates(this);
			tracking = false;
			postNotification("Voo","Service running.","Stopped Tracking", UIDashboard.class);
		}
	}


	@SuppressWarnings("unchecked")
	public void onLocationChanged(Location location) {
		// TODO Auto-generated method stub
		long timePassed = (System.currentTimeMillis() / 1000L) - lastDataSend;
		if (timePassed >= 30){
			lastDataSend = System.currentTimeMillis() / 1000L;
			ArrayList<String> data = new ArrayList<String>();
			data.add(Double.toString(location.getLongitude()));
			data.add(Double.toString(location.getLatitude()));
			data.add(Double.toString(location.getAltitude()));
			if (WebData.isNetworkAvailable(this)){
				new sendData().execute(data);
			}
		}		
	}

	private void aquireWakeLock() {
		final PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
		this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VOO");
		this.wakeLock.acquire();
		debug.postLog(Log.DEBUG, "Service", "Wake Lock: " + this.wakeLock);
	}

	private void releaseWakeLock() {
		if( this.wakeLock == null )
			return;
		this.wakeLock.release();
		this.wakeLock = null;
		debug.postLog(Log.DEBUG, "Service", "Wake Lock: Released");
	}

	public void getProvider(){
		Log.d("", "Get Provider");
		if (lm.equals(null)){
			lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		}
		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		String provider = lm.getBestProvider(criteria, true);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
		lm.requestLocationUpdates(provider, 0, 0, this);
	}

	public void onProviderDisabled(String provider) {
		getProvider();
		debug.postLog(Log.DEBUG, "Service", "onProviderDisabled()");
	}

	public void onProviderEnabled(String provider) {
		debug.postLog(Log.DEBUG, "Service", "onProviderEnabled()");
		getProvider();

	}

	public void onStatusChanged(String provider, int status, Bundle extras) {

	}
	private class MyReceiver extends BroadcastReceiver{
		Background main = null;
		MyReceiver(Background main){
			this.main = main;
		}
		@Override
		public void onReceive(Context arg0, Intent arg1) {
			main.toggleTracking();

		}

	}
	public class sendData extends AsyncTask < ArrayList<String> , Context , Void > {
		@ Override
		protected Void doInBackground ( ArrayList<String> ... params ) {
			DataFunc userFunction = new DataFunc();
			JSONObject json = userFunction.sendDeviceLocation(Background.this, params[0].get(0), params[0].get(1), params[0].get(2));
			try {
				if (json.getString(KEY_SUCCESS) != null) {
					String res = json.getString(KEY_SUCCESS);                     
					if(Integer.parseInt(res) == 1){
						Log.i("","Location sent OK");
					}else{
						Log.d("",json.getString(KEY_ERROR_MSG));

					}
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
			return null;
		}

		@ Override
		protected void onPostExecute ( Void result ) {
		}
	}
}